package com.cocostudio.erpapp.web;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;

import android.util.Log;

import com.cocostudio.erpapp.common.Debug;
import com.cocostudio.erpapp.vo.ValueObject;
import com.google.gson.Gson;

public final class ServerRequester {
    private static final String TAG = "ServerRequester";
    private static final String BASE_URL = "http://www.mobileerp/jsn/";
    private static final String EID = "cmefd41d8cd98f00b204e9800998";
    private static final int SO_TIMEOUT = 5000;
    private static final int CONNECTION_TIMEOUT = 5000;

    public static Result requestByGet(final String api, final Parameters params) {
        if (Debug.LOGD) {
            Log.d(TAG, "requestByGet. api=" + api + ", params=" + params);
        }
        params.put(Keys.EID, EID);
        return request(api, params, true);
    }

    private static Result request(final String api, final Parameters params, final boolean useGet) {
        Result result = new Result();
        String url = BASE_URL + api + ".htm";
        HttpResponse response = null;
        InputStream content = null;
        try {
            response = useGet ? performGet(url, params) : performPost(url, params);
            int statusCode = response.getStatusLine().getStatusCode();
            result.statusCode = statusCode;
            if (HttpStatus.SC_OK == statusCode) {
                content = response.getEntity().getContent();
              //  result.vo = ResponseParser.parse(new Gson(), new InputStreamReader(content, "utf-8"), api, params.getAction());
            }
        } catch (Exception e) {
            if (Debug.LOGE) {
                Log.e(TAG, "failed to perform requesting to " + url, e);
            }
        } finally {
            if (content != null) {
                try {
                    content.close();
                } catch (IOException e) {
                }
            }
            if (response != null) {
                try {
                    response.getEntity().consumeContent();
                } catch (IOException e) {
                }
            }
        }
        return result;

    }
 
    
    public String convertStreamToString(InputStream is) {   
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));   
        StringBuilder sb = new StringBuilder();   
        String line = null;   
        try { 
                 while ((line = reader.readLine()) != null) {   
                     sb.append(line + "/n");   
                 }   
         } catch (IOException e) {   
                 e.printStackTrace();   
        } finally {   
                 try {   
                     is.close();   
                 } catch (IOException e) {   
                     e.printStackTrace();   
                 }               
        } 
        return sb.toString();
     }
             
    public static HttpResponse performGet(String url, Parameters params) throws Exception {
        StringBuilder sb = new StringBuilder();
        sb.append("?");
        if (params != null && !params.isEmpty()) {
            for (Entry<String, String> entry : params.entrySet()) {
                String value = entry.getValue();
                sb.append("&").append(entry.getKey()).append("=").append(value == null ? null : URLEncoder.encode(value));
            }
        }
        url += sb.toString();
        if (Debug.LOGD) {
            Log.d(TAG, "performGet. url=" + url);
        }
        HttpParams httpParams = new BasicHttpParams();
        HttpConnectionParams.setConnectionTimeout(httpParams, CONNECTION_TIMEOUT);
        HttpConnectionParams.setSoTimeout(httpParams, SO_TIMEOUT);
        final DefaultHttpClient client = new DefaultHttpClient();
        client.setParams(httpParams);
        return client.execute(new HttpGet(url));
    }

    private static HttpResponse performPost(String url, Parameters params) throws Exception {
        if (Debug.LOGD) {
            Log.d(TAG, "performPost. url=" + url);
        }
        HttpParams httpParams = new BasicHttpParams();
        HttpConnectionParams.setConnectionTimeout(httpParams, CONNECTION_TIMEOUT);
        HttpConnectionParams.setSoTimeout(httpParams, SO_TIMEOUT);
        final DefaultHttpClient client = new DefaultHttpClient();
        client.setParams(httpParams);
        HttpPost post = new HttpPost(url);
        ArrayList<NameValuePair> nvps = null;
        if (params != null && !params.isEmpty()) {
            nvps = new ArrayList<NameValuePair>();
            for (Entry<String, String> entry : params.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                if (Debug.LOGD) {
                    Log.d(TAG, "performPost. parameter[" + key + "=" + value + "]");
                }
                nvps.add(new BasicNameValuePair(key, value));
            }
        }
        if (nvps != null) {
            post.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
        }
        return client.execute(post);
    }

    public static class Parameters {
        private HashMap<String, String> params;

        public Parameters(String action) {
            params = new HashMap<String, String>();
            if (action != null) {
                params.put(Keys.ACT, action);
            }
        }

        public void put(String key, String value) {
            params.put(key, value);
        }

        Set<Entry<String, String>> entrySet() {
            return params.entrySet();
        }

        boolean isEmpty() {
            return params.isEmpty();
        }

        public String getValue(String key) {
            return params.get(key);
        }

        String getAction() {
            return params.get(Keys.ACT);
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            for (Entry<String, String> entry : params.entrySet()) {
                sb.append("\n#").append(entry.getKey()).append("=").append(entry.getValue());
            }
            return sb.toString();
        }
    }

    public static class Result {
        public int statusCode = HttpStatus.SC_BAD_REQUEST;
        public ValueObject vo;

        public boolean isOk() {
            return HttpStatus.SC_OK == statusCode;
        }

        @Override
        public String toString() {
            return "statusCode=" + statusCode + ", vo=" + vo;
        }
    }
}
